package com.reading.core.manager.impl;

import com.reading.common.config.SequenceConfig;
import com.reading.common.constant.BookUpdateStatusType;
import com.reading.common.constant.SequenceConstant;
import com.reading.common.constant.StatusType;
import com.reading.common.entity.view.*;
import com.reading.common.persistence.view.*;
import com.reading.common.utils.StringUtil;
import com.reading.core.exception.AloneException;
import com.reading.core.exception.book.BookAddChapterFailException;
import com.reading.core.exception.book.BookChapterNotExistsException;
import com.reading.core.exception.book.BookNewBuildFailException;
import com.reading.core.exception.book.BookNotExistsException;
import com.reading.core.exception.system.SequenceNewBuildFailException;
import com.reading.core.manager.IBookManager;
import com.reading.core.utils.CheckUtil;
import com.reading.core.utils.GlobalConstant;
import com.reading.core.utils.UUID;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author guwenqi_1995@163.com
 * @date 2019/7/8 3:23 PM
 **/
@Slf4j
@Service
public class BookManagerImpl implements IBookManager {

    @Resource
    private BookMapper bookMapper;

    @Resource
    private BookLikeMapper bookLikeMapper;

    @Resource
    private BookCollectMapper bookCollectMapper;

    @Resource
    private BookCommentMapper bookCommentMapper;

    @Resource
    private BookChapterMapper bookChapterMapper;

    @Resource
    private BookChapterContentMapper bookChapterContentMapper;

    @Resource
    private SequenceMapper sequenceMapper;

    @Resource
    private SequenceConfig sequenceConfig;

    @Override
    public Book getBook(Integer bookId, Integer userId) throws AloneException {
         CheckUtil.isNull(bookId);

         userId = StringUtil.isNull(userId) ? 0 : userId;

        Book book = bookMapper.selectByPrimaryKey(bookId);
        if (StringUtil.isNull(book)) {
            log.error("查找图书不存在。{}, {}", bookId, userId);
            throw new BookNotExistsException();
        }

        //设置图书章节信息
        setBookChapterInfo(book);
        //设置图书点赞信息
        setBookLikeInfo(book, userId);
        //设置图书收藏信息
        setBookCollectInfo(book, userId);
        //设置图书评论信息
        setBookCommentInfo(book);
        return book;
    }

    @Override
    public List<Book> getBooks(Book book) {
        return bookMapper.selectAllBooks(book);
    }

    @Override
    public BookChapter getBookChapter(Integer bookId, Integer number) throws AloneException {
        CheckUtil.isNull(bookId, number);

        BookChapter chapter = bookChapterMapper.selectByPrimaryKey(bookId, number);
        if (StringUtil.isNull(chapter)) {
            log.error("查找图书章节失败，章节不存在。{}，{}", bookId, number);
            throw new BookChapterNotExistsException();
        }

        String uuid = UUID.getUUID(bookId, number);
        String content = bookChapterContentMapper.selectByUUID(uuid);
        chapter.setContent(content);

        return chapter;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Book save(Book book) throws AloneException {
        CheckUtil.valid(book);

        //保存图书信息
        int bookId = sequenceConfig.getBookId();
        book.setBookId(bookId);
        book.setBookStatus(BookUpdateStatusType.STATUS_1.getCode());
        book.setBookState(StatusType.STATUS_1.getCode());
        if (bookMapper.insert(book) <= GlobalConstant.NUMBER_0) {
            log.error("新建图书失败。");
            throw new BookNewBuildFailException();
        }

        //保存图书评论的sequence
        String key = StringUtil.contentReplace(SequenceConstant.KEY_COMMENT_NUMBER,
                SequenceConstant.PARAM_BOOK_ID, bookId);
        Sequence sequence = new Sequence(key, GlobalConstant.COMMENT_START_NUMBER);
        if (sequenceMapper.insert(sequence) <= GlobalConstant.NUMBER_0) {
            log.error("新建sequence失败。");
            throw new SequenceNewBuildFailException();
        }

        return book;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public BookChapter addChapter(BookChapter chapter) throws AloneException {
        CheckUtil.valid(chapter);


        //添加图书章节信息
        chapter.setChapterNumber(sequenceConfig.getChapterNumber(chapter.getBookId()));
//        chapter.setChapterSize(CheckUtil.getTextNumber(chapter.getContent()));
        if (bookChapterMapper.insert(chapter) <= GlobalConstant.NUMBER_0) {
            log.error("添加图书章节失败。");
            throw new BookAddChapterFailException();
        }

        //添加章节文本信息
        String uuid = UUID.getUUID(chapter.getBookId(), chapter.getChapterNumber());
        BookChapterContent chapterContent = new BookChapterContent(uuid, chapter.getContent());
        CheckUtil.isOk(bookChapterContentMapper.insert(chapterContent));

        return chapter;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addChapter(List<BookChapter> chapters) throws AloneException {
        int bookId = chapters.get(0).getBookId();
        List<BookChapterContent> contents = new ArrayList<>();

        for (int i = 0; i < chapters.size(); i++) {
            chapters.get(i).setChapterNumber(sequenceConfig.getChapterNumber(bookId));

            String uuid = UUID.getUUID(bookId, chapters.get(i).getChapterNumber());
            BookChapterContent chapterContent = new BookChapterContent(uuid, chapters.get(i).getContent());
            contents.add(chapterContent);
        }

        if (bookChapterMapper.insertList(chapters) <= GlobalConstant.NUMBER_0
                || bookChapterContentMapper.insertList(contents) <= GlobalConstant.NUMBER_0) {
            throw new BookAddChapterFailException();
        }
    }


    @Override
    public void modify(Book book) throws AloneException {
        CheckUtil.valid(book);

        //修改图书信息
        CheckUtil.isOk(bookMapper.updateByPrimaryKeySelective(book));
    }

    @Override
    public void modifyChapter(BookChapter chapter) throws AloneException {
        CheckUtil.valid(chapter);

        //修改图书章节信息
        CheckUtil.isOk(bookChapterMapper.updateByPrimaryKeySelective(chapter));

        //修改图书章节内容信息
        String uuid = UUID.getUUID(chapter.getBookId(), chapter.getChapterNumber());
        BookChapterContent chapterContent = new BookChapterContent(uuid, chapter.getContent());
//        CheckUtil.isOk(bookChapterContentMapper.updateByUUID(chapterContent));
    }


    //------------------------------------ 工具方法 -------------------------------------//

    /**
     * 查找图书章节相关信息
     * @param book
     */
    private void setBookChapterInfo(Book book) {
        List<BookChapter> chapters = bookChapterMapper.selectAllChapterByBookId(book.getBookId());

        book.setChapters(chapters);
        book.setLatestChapter(chapters.size() <= 0 ? null : chapters.get(0));
    }

    /**
     * 查找图书点赞相关信息
     * @param book
     * @param userId
     */
    private void setBookLikeInfo(Book book, Integer userId) {
        book.setLikeCount(bookLikeMapper.selectBookLikeCount(book.getBookId()));
        book.setLikeStatus(StringUtil.isNull(userId) ? false :
                bookLikeMapper.selectBookAndUserLikeStatus(book.getBookId(), userId) > 0 );
    }

    /**
     * 查找图书收藏相关信息
     * @param book
     * @param userId
     */
    private void setBookCollectInfo(Book book, Integer userId) {
        book.setCollectCount(bookCollectMapper.selectCollectCountByBookId(book.getBookId()));
        book.setCollectStatus(StringUtil.isNull(userId) ? false :
                bookCollectMapper.selectCollectStatus(book.getBookId(), userId) > 0);
    }

    /**
     * 查找图书评论相关信息
     * @param book
     */
    private void setBookCommentInfo(Book book) {
        List<BookComment> comments = bookCommentMapper.selectCommentByBookId(book.getBookId());

        book.setComments(comments);
        book.setCommentCount(comments.size());
    }
}
